package com.talentech.xprober;

import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import dalvik.system.PathClassLoader;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;

public class Module implements IXposedHookLoadPackage
{

	String[] packageArray = { "com.talentech.xprobedapp",
			"com.example.android.support.appnavigation",
			"com.actionbarsherlock.sample.demos", 
			"com.example.android.supportv4", 
			"com.talentech.xposedtest",
			"com.kiklink.app" };

	private static final String AGENT_CLASS_NAME = "com.talentech.xproberlib.HookAgent";

	private XC_MethodHook hookAgent;
	private LoadPackageParam lpParam;

	public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable
	{
		// log("Loaded app: " + lpparam.packageName);

		boolean isTarget = false;
		for(String packageName : packageArray)
		{
			if(lpparam.packageName.equals(packageName))
			{
				isTarget = true;
				break;
			}
		}
		if (!isTarget)
			return;

		Utils.log("Loaded app: " + lpparam.packageName);

		lpParam = lpparam;

		getAgent();

		findAndHookMethod("dalvik.system.BaseDexClassLoader", lpparam.classLoader, "findClass", String.class, hookAgent);
	}

	private void getAgent()
	{
		Utils.log("getAgent");

		String sourceApk = lpParam.appInfo.publicSourceDir;

		PathClassLoader cl = new PathClassLoader(sourceApk, this.getClass().getClassLoader());

		if (cl != null)
		{
			Utils.log("classloader created");

			try
			{
				Class<?> clazz = cl.loadClass(AGENT_CLASS_NAME);
				Utils.log("class HookAgent loaded");

				Constructor<?> con = clazz.getConstructor();
				Utils.log("get constructor of HookAgent");

				hookAgent = (XC_MethodHook) con.newInstance();
				Utils.log("HookAgent instance created");
			}
			catch (ClassNotFoundException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			catch (NoSuchMethodException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			catch (IllegalArgumentException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			catch (InstantiationException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			catch (IllegalAccessException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			catch (InvocationTargetException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
